package de.bw.jeans.alarminfo;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;

import org.ksoap2.SoapEnvelope;
import org.ksoap2.serialization.SoapObject;
import org.ksoap2.serialization.SoapSerializationEnvelope;
import org.ksoap2.transport.HttpTransportSE;
import org.ksoap2.transport.KeepAliveHttpTransportSE;

import android.app.NotificationManager;
import android.content.Context;
import android.content.Intent;
import android.media.MediaPlayer;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;

import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.GoogleMap.OnMarkerDragListener;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.BitmapDescriptorFactory;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.Marker;
import com.google.android.gms.maps.model.MarkerOptions;

import de.bw.jeans.alarminfo.datatypes.Alarmdaten;
import de.bw.jeans.alarminfo.datatypes.Hydrantendaten;
import de.bw.jeans.alarminfo.tools.AlarmTexteConverter;
import de.bw.jeans.alarminfo.tools.AppPorpertiesData;
import de.bw.jeans.alarminfo.tools.XmlFileTools;

public class ShowAlertMapActivity extends android.support.v4.app.FragmentActivity implements OnMarkerDragListener {

	TextView   tvUeberschrift;
	TextView   tvStrasse;
	TextView   tvAlarmierung;
	String     alarmId;
	GoogleMap  mapView;
	Button	   btnDetails;
	ArrayList<Marker> aktuelleHydranten = new ArrayList<Marker>();
	
	private static MediaPlayer mediaPlayer = null;
		
	/** Called when the activity is first created. */
	@Override
	public void onCreate(Bundle savedInstanceState) {
	    super.onCreate(savedInstanceState);
	    setContentView(R.layout.activity_showalertmap);
	    
	    // Die Daten aus dem XML-File einlesen
	    ArrayList<Alarmdaten> alarmDaten = XmlFileTools.readAlertXmlFile(this);
	    
	    // Prüfen, on der AlarmSound wiedergegeben werden soll
	    File file = this.getFileStreamPath("PlaySound.txt");
	    if(file.exists()) {
	    	mediaPlayer = MediaPlayer.create(ShowAlertMapActivity.this, R.raw.alarmsound);
	    	mediaPlayer.start();
	    	file.delete();
	    }
	    
	    // Die übergebenen Daten einlesen und in Sicherungsfile schreiben oder aus dem Sicherungsfile entnehmen
	    final String SICHERUNGSFILE_NAME = "SelectedAlert.txt";
	    try {
	    	// übergebene Daten einlesen
	    	Bundle extras = getIntent().getExtras();
	    	alarmId = extras.getString("alertId");
	    	
	    	// Daten in ein Sicherungsfile schreiben
	    	FileOutputStream fos = openFileOutput(SICHERUNGSFILE_NAME, Context.MODE_PRIVATE);
	    	fos.write(alarmId.getBytes());
	    	fos.close();
	    }
	    catch(Exception ex) {
	    	// Daten aus dem Sicherungsfile lesen
	    	try {
	    		FileInputStream fis = openFileInput(SICHERUNGSFILE_NAME);
	    		InputStreamReader inputStreamReader = new InputStreamReader(fis);
	    		BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
	    		alarmId = bufferedReader.readLine();
	    		bufferedReader.close();
	    		inputStreamReader.close();
	    		fis.close();
	    	}
	    	catch (Exception ex2) {
	    		Log.d("AlarmInfo", "Fehler beim lesen der Sicherungsfiles \"" + SICHERUNGSFILE_NAME + "\"!");
	    	}
	    }
	    
	    // Die übergebenen Daten in ein Alarm-Objekt umwandeln
	    Alarmdaten alarmdaten = null;
	    for (Alarmdaten serverAlarmdaten : alarmDaten) {
			if(serverAlarmdaten.getAlarmId().equals(alarmId)) {
				alarmdaten = serverAlarmdaten;
				break;
			}
		}

	    // Suchen der verwendeten Views
	    tvUeberschrift 	= (TextView) findViewById(R.id.textView2);
	    tvStrasse 		= (TextView) findViewById(R.id.textView1);
	    tvAlarmierung 	= (TextView) findViewById(R.id.textView5);
	    mapView			= ((SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map)).getMap();
	    btnDetails		= (Button) 	 findViewById(R.id.button1);
	    
	    // Die Karte definieren (Einsatzstelle focusieren)
	    LatLng latLng = new LatLng(Double.valueOf(alarmdaten.getBreitengrad()), Double.valueOf(alarmdaten.getLaengengrad()));
	    mapView.moveCamera(CameraUpdateFactory.newLatLngZoom(latLng, 17));
	    mapView.setOnMarkerDragListener(this);
	    Marker einsatzOrt = mapView.addMarker(new MarkerOptions().position(latLng).draggable(true).icon(BitmapDescriptorFactory.fromResource(R.drawable.pushpin)));

	    // Die Hydranten ermitteln und in die Karte einzeichnen
	    ProximateHydrants hydrants = new ProximateHydrants();
	    hydrants.execute(alarmdaten.getBreitengrad(), alarmdaten.getLaengengrad(), "100");
	    
	    // Die Alarmdaten ausgeben
	    tvUeberschrift.setText(de.bw.jeans.alarminfo.tools.AlarmTexteConverter.getAlarmtextInKlammer(alarmdaten.getStichwort()));
	    tvStrasse.setText(" " + alarmdaten.getEinsatzStrasse());
	    tvAlarmierung.setText(" " + AlarmTexteConverter.getGermanDateFormat(alarmdaten.getMailDatum()) + "  " + alarmdaten.getMailUhrzeit());
	    
	    // Den Button 'Details' definieren
	    btnDetails.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View v) {
				Intent intent = new Intent(v.getContext(), ShowAlertDetailsActivity.class);
				intent.putExtra("alertId", alarmId);
				startActivity(intent);
			}
		});
	}
	
	protected void onStop() {
		super.onStop();
		
	    // Das LED wieder ausschalten
	    NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
	    notificationManager.cancel(0);
	}
	
	@Override
	public void onMarkerDrag(Marker arg0) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void onMarkerDragEnd(Marker arg0) {
		
		// Zuerst alle bisherigen Hydranten entfernen
		for(int i=0; i<aktuelleHydranten.size(); i++) {
			Marker marker = aktuelleHydranten.get(i);
			marker.remove();
		}
		aktuelleHydranten.clear();
		
		// An der neuen Position die Hydranten ermitteln und einzeichnen
		LatLng latLng = arg0.getPosition();
		ProximateHydrants hydrants = new ProximateHydrants();
	    hydrants.execute(String.valueOf(latLng.latitude), String.valueOf(latLng.longitude), "100");
	}

	@Override
	public void onMarkerDragStart(Marker arg0) {
		// TODO Auto-generated method stub
		
	}

	private class ProximateHydrants extends AsyncTask<String, Void, Void> {

		ArrayList<Hydrantendaten> hydrantenliste = new ArrayList<Hydrantendaten>();
		
		@Override
		protected Void doInBackground(String... params) {
			
			String breitengrad = params[0];
			String laengengrad = params[1];
			String abstand     = params[2];
			
			String METHOD_NAME = AppPorpertiesData.getAppProperties().getProperty("PROXYMATE_HYDRANTS_METHOD_NAME");
			String SOAP_ACTION = AppPorpertiesData.getAppProperties().getProperty("PROXYMATE_HYDRANTS_SOAP_ACTION");
			String NAMESPACE   = AppPorpertiesData.getAppProperties().getProperty("PROXYMATE_HYDRANTS_NAMESPACE");
			String URL		   = AppPorpertiesData.getAppProperties().getProperty("PROXYMATE_HYDRANTS_URL");
			
			try {
				SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME);
				
				SoapObject parameters = new SoapObject(NAMESPACE, METHOD_NAME);
				parameters.addProperty("hLatitude" , breitengrad);
				parameters.addProperty("hLongitude", laengengrad);
				parameters.addProperty("hAbstand"  , abstand);
				request.addProperty(METHOD_NAME, parameters);
				
				SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER10);
				envelope.setOutputSoapObject(request);
				
				HttpTransportSE httpTransportSE;
				if(android.os.Build.VERSION.SDK_INT < Build.VERSION_CODES.GINGERBREAD) {
					// Da Markus Geider noch die Version 2.2.2 hat...
					httpTransportSE = new KeepAliveHttpTransportSE(URL);					
				}
				else {					
					httpTransportSE = new HttpTransportSE(URL);
				}
				httpTransportSE.call(SOAP_ACTION, envelope);
				
				SoapObject object = (SoapObject)envelope.getResponse();
				
				for(int i=0; i<object.getPropertyCount(); i++) {
					SoapObject hydrantInfo = (SoapObject)object.getProperty(i);
					
					Hydrantendaten hydrantendaten = new Hydrantendaten();
					hydrantendaten.sethLatitude(hydrantInfo.getPropertyAsString("hLatitude"));
					hydrantendaten.sethLongitude(hydrantInfo.getPropertyAsString("hLongitude"));
					hydrantendaten.sethPosition(hydrantInfo.getPropertyAsString("hPosition"));
					hydrantendaten.sethQualitaet(hydrantInfo.getPropertyAsString("hQualitaet"));
					hydrantendaten.sethArt(hydrantInfo.getPropertyAsString("hArt"));
					hydrantendaten.sethZuleitung(hydrantInfo.getPropertyAsString("hZuleitung"));
					hydrantendaten.sethBemerkung(hydrantInfo.getPropertyAsString("hBemerkung"));
					hydrantendaten.sethAbstand(hydrantInfo.getPropertyAsString("hAbstand"));
					
					hydrantenliste.add(hydrantendaten);
				}
			}
			catch(Exception ex) {
				Log.d("AlarmInfo", ex.getMessage());
			}
			
			return null;
		}
		
	    protected void onPostExecute(Void result) {
	    	// Die ermittelten Hydranten in die Karte einzeichnen
	        for(int i=0; i<hydrantenliste.size(); i++) {
	        	Hydrantendaten hydrantInfo = hydrantenliste.get(i);
	        	
	        	int punktFarbe = R.drawable.punkt_rot;
	        	if(hydrantInfo.gethQualitaet().equals("1")) {
	        		punktFarbe = R.drawable.punkt_gruen;
	        	}
	        	else if (hydrantInfo.gethQualitaet().equals("2")) {
					punktFarbe = R.drawable.punkt_gelb;
				}
	        	
	        	LatLng latLng = new LatLng(Double.valueOf(hydrantInfo.gethLatitude()), Double.valueOf(hydrantInfo.gethLongitude()));
	        	Marker hydrant = mapView.addMarker(new MarkerOptions().position(latLng).draggable(false).icon(BitmapDescriptorFactory.fromResource(punktFarbe)).title(hydrantInfo.gethArt() + " (" + hydrantInfo.gethZuleitung() + " mm²)").snippet("Position: " + hydrantInfo.gethPosition()));
	        	aktuelleHydranten.add(hydrant);
	        }
	    }
		
	}
}
